/*
 * Copyright 2003-2005 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

using System;
namespace argot
{
	
	public class DynamicTypeMap:ReferenceTypeMap
	{

		private int _lastMapId;
		
		public DynamicTypeMap(TypeLibrary library, TypeMap refMap):base(library, refMap)
		{
			_lastMapId = 1;
		}
		
		public DynamicTypeMap(TypeLibrary library):base(library, null)
		{
			ReferenceMap = this;
			_lastMapId = 1;
		}
		
		private int NextId
		{
			get
			{
				int id;
				
				while (true)
				{
					id = _lastMapId;
					_lastMapId++;
					
					try
					{
						this.GetSystemId(id);
					}
					catch (TypeException)
					{
						// type wasn't found to be mapped.  This one is ok.
						break;
					}
				}
				
				return id;
			}
			
		}

		public override void Map(int id, int systemId)
		{
			base.Map(id, systemId);
		}
		
		public override int GetId(System.String name)
		{
			
			try
			{
				return base.GetId(name);
			}
			catch (TypeException)
			{
				try
				{
					int id = NextId;
					this.Map(id, Library.GetId(name));
					return id;
				}
				catch (TypeException e)
				{
					throw e;
				}
			}
		}
		
		public override int GetId(System.Type clss)
		{
			int systemid = this.Library.GetId(clss);
			
			try
			{
				return this.GetId(systemid);
			}
			catch (TypeException)
			{
				// not mapped yet.
				int id = NextId;
				this.Map(id, systemid);
				return id;
			}
		}
		

		public override TypeWriter GetWriter(int id)
		{
			return base.GetWriter(id);
		}
		
		public override int GetId(int systemid)
		{
			try
			{
				return base.GetId(systemid);
			}
			catch (TypeException)
			{
				return RegisterDynamic(systemid);
			}
		}
		
		private int RegisterDynamic(int systemid)
		{
			int id = NextId;
			this.Map(id, systemid);
			return id;
		}
	}
}